// get
{
  const myObject = {
    foo: 1,
    bar: 2,
    get baz() {
      return this.foo + this.bar
    }
  }
  console.log(Reflect.get(myObject, 'foo')) // 1
  console.log(Reflect.get(myObject, 'bar')) // 2
  console.log(Reflect.get(myObject, 'baz')) // 3
  const myReceiverObject = {
    foo: 4,
    bar: 9
  }
  console.log(Reflect.get(myObject, 'baz', myReceiverObject)) // 13
}
// set
{
  const myObject = {
    foo: 1,
    set bar (value) {
      return this.foo = value
    }
  }
  console.log(myObject.foo) // 1
  Reflect.set(myObject, 'foo', 2)
  console.log(myObject.foo) // 2
  Reflect.set(myObject, 'bar', 3)
  console.log(myObject.foo) // 3
  const myReceiverObject = {
    foo: 0
  }
  Reflect.set(myObject, 'bar', 20, myReceiverObject)
  console.log(myReceiverObject.foo) // 20
  console.log(myObject.foo) // 3

  // 触发proxy的Proxy.defineProperty
  {
    let p = {
      a: 'a'
    }
    let handler = {
      set (target, key, value, receiver) {
        console.log('set')
        Reflect.set(target, key, value, receiver)
      },
      defineProperty (target, key, attribute) {
        console.log('defineProperty')
        Reflect.defineProperty(target, key, attribute)
      }
    }
    let obj = new Proxy(p, handler)
    obj.a = 'A'
    // set
    // definePoperty
  }
}

// has
{
  const myObject = {
    foo: 1
  }
  console.log(Reflect.has(myObject, 'toString')) // true
  console.log(Reflect.has(myObject, 'foo')) // true
}
// delete
{
  const myObject = {foo: 'bar'}
  Reflect.deleteProperty(myObject, 'foo')
  console.log(Reflect.get(myObject, 'foo')) // undefined
}

// constructor
{
  function Greet (name) {
    this.name = name
  }
  const ins = Reflect.construct(Greet, [1])
  console.log(ins.name) // 1
}

// getPrototypeOf(obj)
{
  console.log(Reflect.getPrototypeOf({})) // node环境下是一个没有任何属性的字面量对象,浏览器环境下打印出Object的原型
}
// setPrototypeOf(obj, newPro)
{
  const obj = {}
  console.log(Reflect.setPrototypeOf(obj, {name: 'lee'})) // true
  console.log(Reflect.getPrototypeOf(obj)) // { name: 'lee' }
}
// apply()
{
  const arr = [1, 2]
  console.log(Reflect.apply(Object.prototype.toString, arr, [])) // [object Array]
}

// defineProperty
{
  const obj = {}
  Reflect.defineProperty(obj, 'name', {
    value: 1
  })
  console.log(obj.name) // 1
  console.log(Reflect.get(obj, 'name')) // 1
}
// Reflect.ownKeys(target)
{
  const myObject = {
    foo: 1,
    bar: 2,
    [Symbol.for('baz')]: 3,
    [Symbol.for('bing')]: 4
  }
  console.log(Reflect.ownKeys(myObject)) // [ 'foo', 'bar', Symbol(baz), Symbol(bing) ]
}
// 使用Proxy实现观察者模式
{
  const queueObservers = new Set()
  const observer = fn => queueObservers.add(fn)
  const observable = obj => new Proxy(obj, {
    set (target, key, value, receiver) {
      const result = Reflect.set(target, key, value, receiver)
      queueObservers.forEach(observer => observer())
      return result
    }
  })
  const person = observable({
    name: '张三',
    age: '20'
  })
  observer(() => {
    console.log(`${person.name}, ${person.age}`)
  })
  person.name = '李四' // 李四, 20
}




